package cn.han.design;

/*本类用于实现单例设计模式优化实现方案2：懒汉式
 * 关于单例设计模式的两种实现方式
 * 1.恶汉式：不管你用不用这个类的对象，都会直接创建一个
 * 2.懒汉式：先不给你创建这个类的对象，等你需要的时候在创建--延迟加载的思想
 * 延迟加载的思想：是指不会再第一时间就把对象创建好占用内存
 *               而是什么时候用到，什么时候再去创建对象
 * 3.线程安全问题：由于我们存在唯一的对象single2，并且多条语句都操作了这个变量
 * 如果将程序放到多线程的环境下，就容易出现数据安全的问题，所以解决方案：
 * 1）将3条语句都是用同步代码块包裹，保证同步排队的效果
 * 2）由于方法只有3条语句，所以也可以将本方法设置为同步方法*/
public class Singleton2 {
    public static void main(String[] args) {
        MySingle2 single4 = MySingle2.getSingle2();
        MySingle2 single3 = MySingle2.getSingle2();
        System.out.println(single3 == single4);
        System.out.println(single3);
        System.out.println(single4);
    }
}

class MySingle2 {
    static Object o = new Object();

    private MySingle2() {
    }

    private static MySingle2 single2;//创建本类对象的引用类型变量，用来保存对象的地址值，默认值是null

    synchronized public static MySingle2 getSingle2() {
        //有共享数据+多条语句操作数据，所以尽量提前处理，避免多线程数据安全隐患
        //解决方案一：加同步代码块
        //解决方案二：将本方法设置为同步方法，因为这个方法里所有的语句都需要同步
        //判断之前是否创建过对象，之前创建过就直接走return
        synchronized (o) {
            if (single2 == null) {//说明之前没有创建过对象
                single2 = new MySingle2();//没创建过才创建，并赋值给single2
            }
            return single2;
        }
    }
}